
// PlayerUpView.m - see header file for more info

#import <gamekit/gamekit.h>	// Header file

@implementation PlayerUpView

- initFrame:(const NXRect *)frm   // designated initializer for a view
{
	[super initFrame:frm];
	margin = 2.0; // "margin" around the player image
	numUp = 0; // start with zero; up to game to set properly at start
	return self;
}

- setImage:anImage { image = anImage; return self; }
- (int)numUp { return numUp; }
- setMargin:(NXCoord)newMargin { margin = newMargin; return self; }

- setImageFrame:(NXRect *)aRect
{
	NXSetRect(&imageFrame, NX_X(aRect), NX_Y(aRect),
			NX_WIDTH(aRect), NX_HEIGHT(aRect));
	return self;
}

- incNumUp:sender
{
	numUp++; [self update];
#ifdef NOISYDEBUG
		fprintf(stderr, "Inc number of one ups to %d.\n", numUp);
#endif
	if ([delegate respondsTo:@selector(oneUpAdded)])
		[delegate oneUpAdded];
	return self;
}

- setNumUp:(int)newNumUp
{
	if (numUp == newNumUp) return self; // no change so leave.
	numUp = newNumUp;
#ifdef NOISYDEBUG
		fprintf(stderr, "Set number of one ups to %d.\n", numUp);
#endif
	// this message usually comes at start of game, so assume
	// that we should reset the extra man bonus points...
	[extraManBonusTracker resetBonus];
	return [self update];
}

- (BOOL)decNumUp:sender // returns NO if player has no xtra men left.
{
	if (numUp) {
		numUp--; [self update];
#ifdef NOISYDEBUG
		fprintf(stderr, "Dec number of one ups to %d.\n", numUp);
#endif
		if ([delegate respondsTo:@selector(oneUpUsed)])
			[delegate oneUpUsed];
		return YES;
	}
	if ([delegate respondsTo:@selector(allOneUpsGone)])
		[delegate allOneUpsGone];
	return NO;
}

- drawSelf:(NXRect *)rects :(int)rectCount	// redraws the view.
{	// this is inefficient; I always redraw the entire view...
	// Since this View is redrawn so little, I don't care-it's good enough.
	int baseCount = numUp; // counts down to zero to fill view
	int x, y;
	NXPoint pos; // where we'll splat the base in the view
	
    PSsetgray(NX_LTGRAY); // opaque background
	NXRectFill(&bounds);
	if (baseCount > 0) {
		// start at bottom row; move up
		y = 0; pos.y = (imageFrame.size.height + margin * 2) * y + margin;
		while ((pos.y < bounds.size.height) && baseCount) { // y loop
			// start at left, move right
			x = 0; pos.x = (imageFrame.size.width + margin * 2) * x + margin;
			while ((pos.x < bounds.size.width) && baseCount) { // x loop
				// splat the base on the screen
				[image composite:NX_SOVER fromRect:&imageFrame toPoint:&pos];
				baseCount--; // update vars
				x++; pos.x = (imageFrame.size.width + margin * 2) * x + margin;
			}
			y++; pos.y = (imageFrame.size.height + margin * 2) * y + margin;
	}	}
	return self;
}

- read:(NXTypedStream *)stream
{
	[super read:stream];
	NXReadTypes(stream, "if", &numUp, &margin);
	NXReadRect(stream, &imageFrame);
	image = NXReadObject(stream);
	return self;
}

- write:(NXTypedStream *)stream // you must call NXWriteRootObject to
{ // invoke this method
	[super write:stream];
	NXWriteTypes(stream, "if", &numUp, &margin);
	NXWriteRect(stream, &imageFrame);
	NXWriteObjectReference(stream, image);
	return self;
}

- scoreChangedFrom:(int)oldScore to:(int)newScore
{
	// use a bonus tracker to give out extra guys...we need to be the score
	// keeper's delegate for this to work!  (GameBrain will do that for us)
#ifdef NOISYDEBUG
	fprintf(stderr, "Score change from %d to %d, xtra man at %d.  ",
			oldScore, newScore, [extraManBonusTracker bonusValue]);
#endif
	if (!extraManBonusTracker) return self; // no bonuses given...
	if (([extraManBonusTracker bonusValue] >= oldScore) &&
			([extraManBonusTracker bonusValue] <= newScore)) { // crossed it!
		[extraManBonusTracker advanceBonus];
		[self incNumUp:self];
		if ([delegate respondsTo:@selector(oneUpAwarded)])
			[delegate oneUpAwarded];
#ifdef NOISYDEBUG
		fprintf(stderr, "Bonus awarded.");
#endif
	}
#ifdef NOISYDEBUG
	fprintf(stderr, "\n");
#endif
	return self;
}

- setExtraManBonusTracker:tracker
{
	id oldExtraManBonusTracker = extraManBonusTracker;
	if ([tracker isKindOf:[BonusTracker class]]) { // make sure right class
		extraManBonusTracker = tracker;
		return oldExtraManBonusTracker;
	}
	return nil;
}

- extraManBonusTracker { return extraManBonusTracker; }
- delegate { return delegate; }
- setDelegate:anObject
{
	id oldDelegate = delegate;
	delegate = anObject;
	return oldDelegate;
}

@end
